﻿using CTP.CRM.Application;
using CTP.CRM.Core;
using CTP.CRM.Core.Cors;
using CTP.CRM.Core.Filter;
using CTP.CRM.Core.JsonSerialization;
using CTP.CRM.Core.Localization;
using CTP.CRM.Core.Prometheus;
using CTP.CRM.Core.Redis;
using CTP.CRM.Core.Swagger;
using CTP.CRM.Core.Rabbit;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Auditing;
using Volo.Abp.Autofac;
using Volo.Abp.Json;
using Volo.Abp.Modularity;


[assembly: HostingStartup(typeof(HostingStartup))]
namespace CTP.CRM.Api
{
    //[DependsOn]属性声明模块依赖
    [DependsOn(
       typeof(AbpAutofacModule),   //依赖注入容器的核心模块
       typeof(CtpAbpCodeModule),   //自定义的基础模块
       typeof(ApplicationModule),  //自定义的应用模块
       typeof(AbpAspNetCoreMvcModule), //它负责将 ABP 框架与 ASP.NET Core MVC 框架进行桥接和配置
       typeof(AbpAspNetCoreSerilogModule)  //用于集成 Serilog 日志系统的核心模块
   )]
    public class ApiModule : AbpModule
    {
        /// <summary>
        /// 配置服务
        /// </summary>
        /// <param name="context"></param>
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            //获取环境和配置信息
            var environment = context.Services.GetHostingEnvironment();
            var configuration = context.Services.GetConfiguration();
            context.Services.AddSwagger();  //添加Swagger

            //添加过滤器相关配置
            context.Services.AddMvc(options =>
            {
                options.Filters.AddService<GlobalExceptionFilter>(); //用于全局异常处理，捕获未处理的异常并返回统一格式的错误响应。
                options.Filters.AddService<RequestLogFilter>();      //用于记录请求日志，有助于调试和监控。
                options.Filters.AddService<UnifyResultFilter>();     //用于统一API的结果返回格式，确保客户端接收到的数据格式一致。
            }).AddNewtonsoftJson();

            context.Services.AddFluentValidationAutoValidation().AddFluentValidationClientsideAdapters(); //添加FluentValidation自动验证

            //Json格式化全局处理
            context.Services.Configure<MvcNewtonsoftJsonOptions>(options =>
            {
                //将.NET对象中的属性名转换为驼峰式命名，以便JavaScript客户端更好地处理JSON数据。
                options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
                //自定义日期时间的序列化格式为"yyyy-MM-dd HH:mm:ss"。
                options.SerializerSettings.Converters.Add(new DateTimeJsonConverter("yyyy-MM-dd HH:mm:ss"));
                //自定义长整型数据的序列化行为。
                options.SerializerSettings.Converters.Add(new LongJsonConverter());
            });

            //Rabbitmq
            context.Services.AddRabbitBoot(options =>
            {
                options.ConnectionString = $"amqp://{configuration["RabbitMQ:UserName"]}:" +
                                           $"{configuration["RabbitMQ:Password"]}@" +
                                           $"{configuration["RabbitMQ:HostName"]}:" +
                                           $"{configuration["RabbitMQ:Port"]}";
            }, typeof(ApplicationModule).Assembly);

            //配置ABP Json选项
            Configure<AbpJsonOptions>(options =>
            {
                options.InputDateTimeFormats.Add("yyyy-MM-dd HH:mm:ss");
                options.OutputDateTimeFormat = "yyyy-MM-dd HH:mm:ss";
            });
            //禁用ABP审计日志
            Configure<AbpAuditingOptions>(options => { options.IsEnabled = false; });
            //添加Redis
            context.Services.AddRedis();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="context"></param>
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder(); //获取一个IApplicationBuilder实例，该实例用于构建应用程序的请求处理管道
            var env = context.GetEnvironment(); //获取当前应用程序的环境信息

            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage(); //捕获异常并显示详细的错误信息

            app.UseRequestCulture();  //多语言中间件，默认中文
            app.UseRouting();        //路由中间件
            app.UseCorsPolicy();     //启用 CORS
            app.UseConfiguredEndpoints(); //用于注册和启用应用程序的路由系统
            app.UseAbpSwaggerUI(env);  //启用SwaggerUI文档
            app.UseAbpSerilogEnrichers(); //启动日志记录
            app.UsePrometheus();   //添加Prometheus中间件
            #region 启动提示
            Console.WriteLine($@"
                    +-------------------------------------------------------+
                    |                                                       |
                    |                                                       |
                    |                  CRM项目启动成功                      |
                    |                 {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}                   |
                    |                                                       |
                    |                                                       |
                    +-------------------------------------------------------+
                ");
            #endregion
        }
    }
}
